Skip to content

Conversation

@Kogaroshi
Copy link
Contributor

Add 2 new enum tracking in AccessManagerEnumerable :

  • track created/managed roles
  • track target contract with selectors assigned to a specific role

Regarding the Guardian Roles, we need to define in our deployment scripts one or multiple roles acting as Guardians for the current role list. The wanted hierarchy being : DEFAULT_ADMIN => GUARDIAN_ROLE => ROLE (with DEFAULT_ADMIN being the admin of both ROLE & GUARDIAN_ROLE)

@github-actions
Copy link

github-actions bot commented Dec 15, 2025

Forge Build Sizes

Contract Runtime Size (B) Initcode Size (B) Runtime Margin (B) Initcode Margin (B)
AccessManagerEnumerable ↑12% (+1402) 13,539 ↑13% (+1819) 15,353 ↓11% (-1402) 11,037 ↓5% (-1819) 33,799
🔕 Unchanged
Contract Runtime Size (B) Initcode Size (B) Runtime Margin (B) Initcode Margin (B)
AaveOracle 1,842 2,580 22,734 46,572
AccessManager 10,198 11,423 14,378 37,729
Address 44 94 24,532 49,058
Arrays 44 94 24,532 49,058
AssetInterestRateStrategy 2,349 2,534 22,227 46,618
AssetLogic 44 94 24,532 49,058
AuthorityUtils 44 94 24,532 49,058
Bytes 44 94 24,532 49,058
Comparators 44 94 24,532 49,058
Constants 447 499 24,129 48,653
ECDSA 44 94 24,532 49,058
EIP712Hash 441 493 24,135 48,659
EIP712Types 44 94 24,532 49,058
ERC1967Proxy 122 934 24,454 48,218
ERC1967Utils 44 94 24,532 49,058
EnumerableSet 44 94 24,532 49,058
Errors 44 94 24,532 49,058
GatewayBaseWrapper 1,810 2,085 22,766 47,067
Hub 21,587 21,821 2,989 27,331
HubConfigurator 9,981 10,254 14,595 38,898
JsonBindings 9,244 9,296 15,332 39,856
KeyValueList 44 94 24,532 49,058
KeyValueListWrapper 802 830 23,774 48,322
LibBit 44 94 24,532 49,058
LiquidationLogic 6,560 6,612 18,016 42,540
LiquidationLogicWrapper 10,961 11,135 13,615 38,017
Math 44 94 24,532 49,058
MathUtils 44 94 24,532 49,058
MockERC1271Wallet 599 733 23,977 48,419
MockERC20 1,913 2,379 22,663 46,773
MockNoncesKeyed 601 629 23,975 48,523
MockPriceFeed 642 1,300 23,934 47,852
MockSkimSpoke 923 1,082 23,653 48,070
NativeTokenGateway 4,889 5,306 19,687 43,846
NoncesKeyed 425 453 24,151 48,699
Panic 44 94 24,532 49,058
PercentageMath 44 94 24,532 49,058
PercentageMathWrapper 592 620 23,984 48,532
PositionStatusMap 44 94 24,532 49,058
PositionStatusMapWrapper 2,389 2,417 22,187 46,735
Premium 44 94 24,532 49,058
ProxyAdmin 977 1,213 23,599 47,939
RescuableWrapper 770 904 23,806 48,248
ReserveFlagsMap 44 94 24,532 49,058
ReserveFlagsMapWrapper 1,075 1,103 23,501 48,049
Roles 153 203 24,423 48,949
SafeCast 44 94 24,532 49,058
SafeERC20 44 94 24,532 49,058
SharesMath 44 94 24,532 49,058
SignatureChecker 44 94 24,532 49,058
SignatureGateway 9,907 10,418 14,669 38,734
SlotDerivation 44 94 24,532 49,058
SpokeConfigurator 8,659 8,932 15,917 40,220
SpokeInstance 24,541 25,284 35 23,868
StorageSlot 44 94 24,532 49,058
TestnetERC20 2,810 3,686 21,766 45,466
Time 44 94 24,532 49,058
TransientSlot 44 94 24,532 49,058
TransparentUpgradeableProxy 1,073 3,445 23,503 45,707
TreasurySpoke 2,764 3,179 21,812 45,973
UnitPriceFeed 700 1,635 23,876 47,517
UserPositionDebt 44 94 24,532 49,058
UserPositionDebtWrapper 2,695 2,723 21,881 46,429
Utils 44 94 24,532 49,058
WETH9 1,864 2,330 22,712 46,822
WadRayMath 44 94 24,532 49,058
WadRayMathWrapper 1,371 1,399 23,205 47,753

@github-actions
Copy link

github-actions bot commented Dec 15, 2025

♻️ Forge Gas Snapshots

Path Value
snapshots/Hub.Operations.json
mintFeeShares ↑0% (+88) 86,218
🔕 Unchanged
Path Value
snapshots/Hub.Operations.json
add 88,006
add: with transfer 109,613
draw 105,931
eliminateDeficit: full 59,781
eliminateDeficit: partial 69,429
payFee 72,302
refreshPremium 71,999
remove: full 76,993
remove: partial 81,640
reportDeficit 115,076
restore: full 80,471
restore: full - with transfer 173,521
restore: partial 89,137
restore: partial - with transfer 147,400
transferShares 71,192
snapshots/NativeTokenGateway.Operations.json
borrowNative 229,604
repayNative 168,312
supplyAsCollateralNative 160,373
supplyNative 136,476
withdrawNative: full 125,620
withdrawNative: partial 136,825
snapshots/SignatureGateway.Operations.json
borrowWithSig 215,893
repayWithSig 189,160
setSelfAsUserPositionManagerWithSig 74,858
setUsingAsCollateralWithSig 85,053
supplyWithSig 153,205
updateUserDynamicConfigWithSig 62,769
updateUserRiskPremiumWithSig 61,579
withdrawWithSig 131,713
snapshots/Spoke.Getters.json
getUserAccountData: supplies: 0, borrows: 0 11,937
getUserAccountData: supplies: 1, borrows: 0 48,600
getUserAccountData: supplies: 2, borrows: 0 80,378
getUserAccountData: supplies: 2, borrows: 1 100,166
getUserAccountData: supplies: 2, borrows: 2 118,596
snapshots/Spoke.Operations.ZeroRiskPremium.json
borrow: first 191,325
borrow: second action, same reserve 171,297
liquidationCall (receiveShares): full 300,391
liquidationCall (receiveShares): partial 300,109
liquidationCall: full 310,756
liquidationCall: partial 310,474
permitReserve + repay (multicall) 166,317
permitReserve + supply (multicall) 146,862
permitReserve + supply + enable collateral (multicall) 160,573
repay: full 126,382
repay: partial 131,271
setUserPositionManagerWithSig: disable 44,846
setUserPositionManagerWithSig: enable 68,875
supply + enable collateral (multicall) 140,624
supply: 0 borrows, collateral disabled 123,679
supply: 0 borrows, collateral enabled 106,601
supply: second action, same reserve 106,579
updateUserDynamicConfig: 1 collateral 73,694
updateUserDynamicConfig: 2 collaterals 88,551
updateUserRiskPremium: 1 borrow 94,804
updateUserRiskPremium: 2 borrows 104,619
usingAsCollateral: 0 borrows, enable 58,915
usingAsCollateral: 1 borrow, disable 105,072
usingAsCollateral: 1 borrow, enable 41,803
usingAsCollateral: 2 borrows, disable 126,055
usingAsCollateral: 2 borrows, enable 41,815
withdraw: 0 borrows, full 128,910
withdraw: 0 borrows, partial 133,473
withdraw: 1 borrow, partial 161,036
withdraw: 2 borrows, partial 174,214
withdraw: non collateral 106,544
snapshots/Spoke.Operations.json
borrow: first 262,009
borrow: second action, same reserve 204,981
liquidationCall (receiveShares): full 334,242
liquidationCall (receiveShares): partial 333,960
liquidationCall: full 344,607
liquidationCall: partial 344,325
permitReserve + repay (multicall) 163,504
permitReserve + supply (multicall) 146,862
permitReserve + supply + enable collateral (multicall) 160,573
repay: full 120,544
repay: partial 139,833
setUserPositionManagerWithSig: disable 44,846
setUserPositionManagerWithSig: enable 68,875
supply + enable collateral (multicall) 140,624
supply: 0 borrows, collateral disabled 123,679
supply: 0 borrows, collateral enabled 106,601
supply: second action, same reserve 106,579
updateUserDynamicConfig: 1 collateral 73,694
updateUserDynamicConfig: 2 collaterals 88,551
updateUserRiskPremium: 1 borrow 151,368
updateUserRiskPremium: 2 borrows 204,852
usingAsCollateral: 0 borrows, enable 58,915
usingAsCollateral: 1 borrow, disable 161,636
usingAsCollateral: 1 borrow, enable 41,803
usingAsCollateral: 2 borrows, disable 234,288
usingAsCollateral: 2 borrows, enable 41,815
withdraw: 0 borrows, full 128,910
withdraw: 0 borrows, partial 133,473
withdraw: 1 borrow, partial 215,098
withdraw: 2 borrows, partial 259,848
withdraw: non collateral 106,544

@github-actions
Copy link

github-actions bot commented Dec 15, 2025

🌈 Test Results
No files changed, compilation skipped

Ran 1 test for tests/unit/Spoke/Spoke.MultipleHub.SiloedBorrowing.t.sol:SpokeMultipleHubSiloedBorrowingTest
[PASS] test_siloed_borrowing() (gas: 667419)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 8.50ms (1.18ms CPU time)

Ran 3 tests for tests/unit/Spoke/Spoke.Access.t.sol:SpokeAccessTest
[PASS] testAccess_change_authority() (gas: 2616792)
[PASS] testAccess_hub_functions_callable_by_spokes() (gas: 579019)
[PASS] testAccess_spoke_admin_config_access() (gas: 494835)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 22.44ms (3.19ms CPU time)

Ran 2 tests for tests/unit/Spoke/Spoke.MultipleHub.t.sol:SpokeMultipleHubTest
[PASS] test_borrow_secondHub() (gas: 896989)
[PASS] test_borrow_thirdHub() (gas: 738417)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 32.89ms (3.98ms CPU time)

Ran 1 test for tests/unit/Spoke/Spoke.AccrueInterest.Scenario.t.sol:SpokeAccrueInterestScenarioTest
[SKIP: pending rft] test_accrueInterest_fuzz_RPBorrowAndSkipTime_twoActions((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256),uint40) (runs: 0, μ: 0, ~: 0)
Suite result: ok. 0 passed; 0 failed; 1 skipped; finished in 24.98ms (4.69ms CPU time)

Ran 5 tests for tests/gas/Spoke.Getters.gas.t.sol:SpokeGetters_Gas_Tests
[PASS] test_getUserAccountData() (gas: 22583)
[PASS] test_getUserAccountData_oneSupplies() (gas: 283401)
[PASS] test_getUserAccountData_twoSupplies() (gas: 518556)
[PASS] test_getUserAccountData_twoSupplies_oneBorrows() (gas: 1043202)
[PASS] test_getUserAccountData_twoSupplies_twoBorrows() (gas: 1605780)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 54.58ms (4.69ms CPU time)

Ran 13 tests for tests/gas/Spoke.Operations.gas.t.sol:SpokeOperations_Gas_Tests
[PASS] test_borrow() (gas: 1337080)
[PASS] test_liquidation_full() (gas: 1892942)
[PASS] test_liquidation_partial() (gas: 1892651)
[PASS] test_liquidation_receiveShares_full() (gas: 1882636)
[PASS] test_liquidation_receiveShares_partial() (gas: 1882353)
[PASS] test_multicall_ops() (gas: 1411340)
[PASS] test_repay() (gas: 876502)
[PASS] test_setUserPositionManagerWithSig() (gas: 303821)
[PASS] test_supply() (gas: 542220)
[PASS] test_updateRiskPremium() (gas: 1329028)
[PASS] test_updateUserDynamicConfig() (gas: 581972)
[PASS] test_usingAsCollateral() (gas: 1483101)
[PASS] test_withdraw() (gas: 1964251)
Suite result: ok. 13 passed; 0 failed; 0 skipped; finished in 119.23ms (75.82ms CPU time)

Ran 13 tests for tests/gas/Spoke.Operations.gas.t.sol:SpokeOperations_ZeroRiskPremium_Gas_Tests
[PASS] test_borrow() (gas: 1096592)
[PASS] test_liquidation_full() (gas: 1754651)
[PASS] test_liquidation_partial() (gas: 1754360)
[PASS] test_liquidation_receiveShares_full() (gas: 1744345)
[PASS] test_liquidation_receiveShares_partial() (gas: 1744062)
[PASS] test_multicall_ops() (gas: 1327645)
[PASS] test_repay() (gas: 783742)
[PASS] test_setUserPositionManagerWithSig() (gas: 308269)
[PASS] test_supply() (gas: 544892)
[PASS] test_updateRiskPremium() (gas: 942460)
[PASS] test_updateUserDynamicConfig() (gas: 586420)
[PASS] test_usingAsCollateral() (gas: 1087205)
[PASS] test_withdraw() (gas: 1593456)
Suite result: ok. 13 passed; 0 failed; 0 skipped; finished in 77.20ms (27.00ms CPU time)

Ran 4 tests for tests/unit/Spoke/Spoke.PermitReserve.t.sol:SpokePermitReserveTest
[PASS] test_permitReserve() (gas: 89200)
[PASS] test_permitReserve_forwards_correct_call() (gas: 36410)
[PASS] test_permitReserve_ignores_permit_reverts() (gas: 25167)
[PASS] test_permitReserve_revertsWith_ReserveNotListedIn() (gas: 23207)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 20.83ms (1.06ms CPU time)

Ran 8 tests for tests/unit/misc/EIP712Hash.t.sol:EIP712HashTest
[PASS] test_constants() (gas: 5450)
[PASS] test_hash_borrow_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 4659, ~: 4659)
[PASS] test_hash_repay_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 4615, ~: 4615)
[PASS] test_hash_setUsingAsCollateral_fuzz((address,uint256,bool,address,uint256,uint256)) (runs: 5000, μ: 4902, ~: 4902)
[PASS] test_hash_supply_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 4703, ~: 4703)
[PASS] test_hash_updateUserDynamicConfig_fuzz((address,address,uint256,uint256)) (runs: 5000, μ: 4441, ~: 4441)
[PASS] test_hash_updateUserRiskPremium_fuzz((address,address,uint256,uint256)) (runs: 5000, μ: 4462, ~: 4462)
[PASS] test_hash_withdraw_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 4681, ~: 4681)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 1.06s (1.06s CPU time)

Ran 8 tests for tests/unit/misc/GatewayBase.t.sol:GatewayBaseTest
[PASS] test_constructor() (gas: 17646)
[PASS] test_registerSpoke_fuzz(address) (runs: 5000, μ: 42033, ~: 42033)
[PASS] test_registerSpoke_revertsWith_InvalidAddress() (gas: 13345)
[PASS] test_registerSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 14077)
[PASS] test_registerSpoke_unregister() (gas: 36599)
[PASS] test_renouncePositionManagerRole() (gas: 65281)
[PASS] test_renouncePositionManagerRole_revertsWith_InvalidAddress() (gas: 76695)
[PASS] test_renouncePositionManagerRole_revertsWith_OwnableUnauthorizedAccount() (gas: 76856)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 360.80ms (341.15ms CPU time)

Ran 5 tests for tests/gas/Gateways.Operations.gas.t.sol:NativeTokenGateway_Gas_Tests
[PASS] test_borrowNative() (gas: 922127)
[PASS] test_repayNative() (gas: 996932)
[PASS] test_supplyAndCollateralNative() (gas: 306548)
[PASS] test_supplyNative() (gas: 288339)
[PASS] test_withdrawNative() (gas: 511014)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 38.04ms (4.56ms CPU time)

Ran 17 tests for tests/unit/AaveOracle.t.sol:AaveOracleTest
[PASS] testDECIMALS() (gas: 8379)
[PASS] test_constructor() (gas: 440478)
[PASS] test_deploy_revertsWith_InvalidAddress() (gas: 38111)
[PASS] test_description() (gas: 12049)
[PASS] test_fuzz_constructor(uint8) (runs: 5000, μ: 444405, ~: 444725)
[PASS] test_getReservePrice() (gas: 47398)
[PASS] test_getReservePrice_revertsWith_InvalidPrice() (gas: 46691)
[PASS] test_getReservePrice_revertsWith_InvalidSource() (gas: 10998)
[PASS] test_getReservePrices() (gas: 79462)
[PASS] test_getReservePrices_revertsWith_InvalidSource() (gas: 49374)
[PASS] test_getReserveSource() (gas: 47628)
[PASS] test_setReserveSource() (gas: 44488)
[PASS] test_setReserveSource_revertsWith_InvalidPrice() (gas: 97705)
[PASS] test_setReserveSource_revertsWith_InvalidSource() (gas: 15349)
[PASS] test_setReserveSource_revertsWith_InvalidSourceDecimals() (gas: 15171)
[PASS] test_setReserveSource_revertsWith_OnlySpoke() (gas: 10984)
[PASS] test_spoke() (gas: 10559)
Suite result: ok. 17 passed; 0 failed; 0 skipped; finished in 1.98s (1.97s CPU time)

Ran 6 tests for tests/unit/Spoke/Spoke.Getters.t.sol:SpokeGettersTest
[PASS] test_getLiquidationBonus_configured() (gas: 95132)
Logs:
  Bound result 2
  Bound result 1000000000000000000
  Bound result 4000
  Bound result 900000000000000000

[PASS] test_getLiquidationBonus_fuzz_configured(uint256,uint256,uint16,uint64) (runs: 5000, μ: 93830, ~: 94207)
[PASS] test_getLiquidationBonus_fuzz_notConfigured(uint256,uint256) (runs: 5000, μ: 71392, ~: 71631)
[PASS] test_getLiquidationBonus_notConfigured() (gas: 72663)
Logs:
  Bound result 2
  Bound result 1000000000000000000

[PASS] test_premiumRayGetters() (gas: 1549556)
[PASS] test_protocol_getters() (gas: 284228)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 2.25s (3.21s CPU time)

Ran 4 tests for tests/unit/Spoke/Liquidations/Spoke.LiquidationCall.Dust.t.sol:SpokeLiquidationCallDustTest
[PASS] test_collateralDust_min_debtToTarget() (gas: 7491943)
[PASS] test_debtToCover_exceeds_collateralValue() (gas: 7484523)
[PASS] test_dustColl_allowed() (gas: 7350385)
[PASS] test_dustDebt_allowed() (gas: 7480359)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 47.60ms (20.99ms CPU time)

Ran 17 tests for tests/unit/AccessManagerEnumerable.t.sol:AccessManagerEnumerableTest
[PASS] test_getRoleMembers_fuzz(uint256,uint256) (runs: 5000, μ: 1976192, ~: 1975026)
[PASS] test_getRoleTargetSelectors_fuzz(uint256,uint256) (runs: 5000, μ: 1534767, ~: 1533830)
[PASS] test_grantRole() (gas: 305824)
[PASS] test_grantRole_fuzz(uint64,uint256) (runs: 5000, μ: 919294, ~: 912339)
[PASS] test_revokeRole() (gas: 310356)
[PASS] test_setRoleAdmin_fuzz_trackAdminRoles_multipleRoles_multipleAdmins(uint256) (runs: 5000, μ: 2329096, ~: 2279853)
[PASS] test_setRoleAdmin_fuzz_trackRolesAndTrackAdminRoles_multipleRoles(uint256) (runs: 5000, μ: 1713486, ~: 1671988)
[PASS] test_setRoleAdmin_trackAdminOfRoles() (gas: 708272)
[PASS] test_setRoleAdmin_trackAdminOfRoles_changeAdminRole() (gas: 736661)
[PASS] test_setRoleAdmin_trackAdminRoles() (gas: 653261)
[PASS] test_setRoleAdmin_trackRolesAndTrackAdminRoles() (gas: 267857)
[PASS] test_setRoleGuardian_trackRoles() (gas: 253020)
[PASS] test_setTargetFunctionRole() (gas: 417934)
[PASS] test_setTargetFunctionRole_multipleTargets() (gas: 1108647)
[PASS] test_setTargetFunctionRole_removeTarget() (gas: 900639)
[PASS] test_setTargetFunctionRole_skipAddToAdminRole() (gas: 31815)
[PASS] test_setTargetFunctionRole_withReplace() (gas: 555384)
Suite result: ok. 17 passed; 0 failed; 0 skipped; finished in 25.64s (40.94s CPU time)

Ran 8 tests for tests/gas/Gateways.Operations.gas.t.sol:SignatureGateway_Gas_Tests
[PASS] test_borrowWithSig() (gas: 755549)
[PASS] test_repayWithSig() (gas: 992524)
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 208289)
[PASS] test_setUsingAsCollateralWithSig() (gas: 296234)
[PASS] test_supplyWithSig() (gas: 468497)
[PASS] test_updateUserDynamicConfigWithSig() (gas: 145397)
[PASS] test_updateUserRiskPremiumWithSig() (gas: 143046)
[PASS] test_withdrawWithSig() (gas: 418500)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 43.19ms (8.33ms CPU time)

Ran 6 tests for tests/unit/Hub/Hub.Access.t.sol:HubAccessTest
[PASS] test_change_authority() (gas: 2312566)
[PASS] test_change_role_responsibility() (gas: 123149)
[PASS] test_hub_access_manager_exposure() (gas: 12684)
[PASS] test_hub_admin_access() (gas: 1205766)
[PASS] test_migrate_role_responsibility() (gas: 794358)
[PASS] test_setInterestRateData_access() (gas: 103722)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 23.47ms (3.99ms CPU time)

Ran 19 tests for tests/unit/Hub/Hub.Add.t.sol:HubAddTest
[PASS] test_add_AddCapReachedButNotExceeded_rounding() (gas: 675549)
[PASS] test_add_fuzz_AddCapReachedButNotExceeded(uint40) (runs: 5000, μ: 160268, ~: 160235)
[PASS] test_add_fuzz_multi_asset_multi_spoke(uint256,uint256,uint256) (runs: 5000, μ: 330221, ~: 330441)
[PASS] test_add_fuzz_revertsWith_AddCapExceeded(uint40) (runs: 5000, μ: 113083, ~: 113050)
[PASS] test_add_fuzz_revertsWith_AddCapExceeded_due_to_interest(uint40,uint256,uint256) (runs: 5000, μ: 274582, ~: 274464)
[PASS] test_add_fuzz_revertsWith_InvalidShares_due_to_index(uint256,uint256,uint256) (runs: 5000, μ: 229996, ~: 230208)
[PASS] test_add_fuzz_single_asset(uint256,address,uint256) (runs: 5000, μ: 345525, ~: 345452)
[PASS] test_add_fuzz_single_spoke_multi_add(uint256,uint256) (runs: 5000, μ: 822153, ~: 822213)
[PASS] test_add_multi_add_minimal_shares() (gas: 328544)
[PASS] test_add_revertsWith_AmountDowncastOverflow() (gas: 368149)
[PASS] test_add_revertsWith_InsufficientTransferred() (gas: 64867)
[PASS] test_add_revertsWith_InvalidAmount() (gas: 13475)
[PASS] test_add_revertsWith_InvalidShares() (gas: 230124)
[PASS] test_add_revertsWith_SharesDowncastOverflow() (gas: 228043)
[PASS] test_add_revertsWith_SpokeNotActive() (gas: 98678)
[PASS] test_add_revertsWith_SpokePaused() (gas: 98795)
[PASS] test_add_single_asset() (gas: 333479)
Logs:
  Bound result 2
  Bound result 100000000000000000000

[PASS] test_add_with_increased_index() (gas: 308110)
[PASS] test_add_with_increased_index_with_premium() (gas: 688834)
Suite result: ok. 19 passed; 0 failed; 0 skipped; finished in 48.26s (48.24s CPU time)

Ran 36 tests for tests/unit/Hub/Hub.Config.t.sol:HubConfigTest
[PASS] test_addAsset_fuzz(address,uint8,address) (runs: 5000, μ: 916238, ~: 916272)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_feeReceiver(address,uint8,address) (runs: 5000, μ: 46699, ~: 47026)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_irStrategy(address,uint8,address) (runs: 5000, μ: 46730, ~: 47057)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_underlying(uint8,address,address) (runs: 5000, μ: 37678, ~: 37678)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAssetDecimals(address,uint8,address,address) (runs: 5000, μ: 47245, ~: 47037)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAssetDecimals_tooLow(address,uint8,address,address) (runs: 5000, μ: 47495, ~: 47736)
[PASS] test_addAsset_fuzz_reverts_InvalidIrData(address,uint8,address,address) (runs: 5000, μ: 41050, ~: 36307)
[PASS] test_addAsset_revertsWith_BlockTimestampDowncastOverflow() (gas: 767778)
[PASS] test_addAsset_revertsWith_DrawnRateDowncastOverflow() (gas: 764724)
[PASS] test_addAsset_reverts_UnderlyingAlreadyListed() (gas: 47840)
[PASS] test_addSpoke_fuzz(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 125952, ~: 126006)
[PASS] test_addSpoke_fuzz_revertsWith_AssetNotListed(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 34832, ~: 34819)
[PASS] test_addSpoke_fuzz_revertsWith_InvalidAddress_spoke(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 33421, ~: 33475)
[PASS] test_addSpoke_revertsWith_SpokeAlreadyListed() (gas: 38964)
[PASS] test_hub_deploy_revertsWith_InvalidAddress() (gas: 47568)
[PASS] test_hub_max_riskPremium() (gas: 8570)
[PASS] test_updateAssetConfig_NewFeeReceiver_noFees() (gas: 732631)
[PASS] test_updateAssetConfig_NewFeeReceiver_revertsWith_SpokeNotActive_noFees() (gas: 626485)
[PASS] test_updateAssetConfig_UseExistingSpokeAndListedAsFeeReceiver_revertsWith_SpokeAlreadyListed() (gas: 72156)
[PASS] test_updateAssetConfig_fuzz(uint256,(address,uint16,address,address)) (runs: 5000, μ: 269315, ~: 269640)
[PASS] test_updateAssetConfig_fuzz_FromZeroLiquidityFee(uint256,uint16) (runs: 5000, μ: 823766, ~: 823711)
[PASS] test_updateAssetConfig_fuzz_LiquidityFee(uint256,uint16) (runs: 5000, μ: 725833, ~: 725778)
[PASS] test_updateAssetConfig_fuzz_NewFeeReceiver(uint256) (runs: 5000, μ: 831997, ~: 832116)
[PASS] test_updateAssetConfig_fuzz_NewInterestRateStrategy(uint256) (runs: 5000, μ: 1208750, ~: 1208869)
[PASS] test_updateAssetConfig_fuzz_ReuseFeeReceiver_revertsWith_SpokeAlreadyListed(uint256) (runs: 5000, μ: 884542, ~: 884661)
[PASS] test_updateAssetConfig_fuzz_Scenario(uint256) (runs: 5000, μ: 683390, ~: 683441)
[PASS] test_updateAssetConfig_fuzz_UseExistingSpokeAsFeeReceiver_revertsWith_SpokeAlreadyListed(uint256) (runs: 5000, μ: 71828, ~: 71828)
[PASS] test_updateAssetConfig_fuzz_revertsWith_InvalidInterestRateStrategy(uint256) (runs: 5000, μ: 60032, ~: 60083)
[PASS] test_updateAssetConfig_fuzz_revertsWith_InvalidLiquidityFee(uint256,(address,uint16,address,address)) (runs: 5000, μ: 41490, ~: 41395)
[PASS] test_updateAssetConfig_fuzz_revertsWith_InvalidReinvestmentController() (gas: 490843)
[PASS] test_updateAssetConfig_fuzz_revertsWith_calculateInterestRateReverts(uint256,(address,uint16,address,address)) (runs: 5000, μ: 202755, ~: 203039)
[PASS] test_updateAssetConfig_fuzz_revertsWith_setInterestRateDataReverts(uint256,(address,uint16,address,address)) (runs: 5000, μ: 65606, ~: 65509)
[PASS] test_updateAssetConfig_oldFeeReceiver_flags() (gas: 845462)
Logs:
  Bound result 1
  Bound result 500
  Bound result 3
  Bound result 1000
  Bound result 5
  Bound result 500
  Bound result 3
  Bound result 1000

[PASS] test_updateSpokeConfig_fuzz(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 58563, ~: 58625)
[PASS] test_updateSpokeConfig_fuzz_revertsWith_SpokeNotListed(uint256,address,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 40531, ~: 40592)
[PASS] test_updateSpokeConfig_revertsWith_AssetNotListed() (gas: 29444)
Suite result: ok. 36 passed; 0 failed; 0 skipped; finished in 100.82s (100.80s CPU time)

Ran 16 tests for tests/unit/Hub/Hub.Draw.t.sol:HubDrawTest
[PASS] test_draw_DifferentSpokes() (gas: 362512)
[PASS] test_draw_fuzz_IncreasedBorrowRate(uint256,uint256) (runs: 5000, μ: 705240, ~: 705273)
[PASS] test_draw_fuzz_amounts_same_block(uint256,uint256) (runs: 5000, μ: 289000, ~: 288910)
[PASS] test_draw_fuzz_revertsWith_DrawCapExceeded(uint40) (runs: 5000, μ: 81503, ~: 81470)
[PASS] test_draw_fuzz_revertsWith_DrawCapExceeded_due_to_interest(uint40,uint256,uint256) (runs: 5000, μ: 293952, ~: 294219)
[PASS] test_draw_fuzz_revertsWith_InsufficientLiquidity(uint256,uint256) (runs: 5000, μ: 34069, ~: 33863)
[PASS] test_draw_fuzz_revertsWith_InsufficientLiquidity_due_to_draw(uint256) (runs: 5000, μ: 175324, ~: 175045)
[PASS] test_draw_fuzz_revertsWith_InsufficientLiquidity_due_to_remove(uint256) (runs: 5000, μ: 136211, ~: 136013)
[PASS] test_draw_fuzz_revertsWith_InvalidAddress(uint256) (runs: 5000, μ: 15757, ~: 15757)
[PASS] test_draw_revertsWith_DrawCapExceeded_due_to_deficit() (gas: 274430)
[PASS] test_draw_revertsWith_InsufficientLiquidity() (gas: 28097)
[PASS] test_draw_revertsWith_InsufficientLiquidity_due_to_draw() (gas: 171620)
[PASS] test_draw_revertsWith_InsufficientLiquidity_due_to_remove() (gas: 133323)
[PASS] test_draw_revertsWith_InvalidAmount() (gas: 15877)
[PASS] test_draw_revertsWith_SpokeNotActive() (gas: 59800)
[PASS] test_draw_revertsWith_SpokePaused() (gas: 59873)
Suite result: ok. 16 passed; 0 failed; 0 skipped; finished in 25.30s (25.28s CPU time)

Ran 7 tests for tests/unit/Spoke/Spoke.AccrueInterest.t.sol:SpokeAccrueInterestTest
[PASS] test_accrueInterest_NoActionTaken() (gas: 132063)
[PASS] test_accrueInterest_NoInterest_NoDebt(uint40) (runs: 5000, μ: 639083, ~: 638923)
[PASS] test_accrueInterest_NoInterest_OnlySupply(uint40) (runs: 5000, μ: 252245, ~: 252281)
[PASS] test_accrueInterest_TenPercentRp(uint256,uint40) (runs: 5000, μ: 584696, ~: 585179)
[PASS] test_accrueInterest_fuzz_BorrowAmountAndSkipTime(uint256,uint40) (runs: 5000, μ: 542200, ~: 542205)
[PASS] test_accrueInterest_fuzz_RPBorrowAndSkipTime((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256),uint40) (runs: 5000, μ: 3865068, ~: 3882582)
[PASS] test_accrueInterest_fuzz_RatesRPBorrowAndSkipTime((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256),(uint96,uint96,uint96,uint96),uint40) (runs: 5000, μ: 3933349, ~: 3949750)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 204.95s (301.71s CPU time)

Ran 6 tests for tests/unit/Hub/Hub.EliminateDeficit.t.sol:HubEliminateDeficitTest
[PASS] test_eliminateDeficit(uint256) (runs: 5000, μ: 657194, ~: 657194)
[PASS] test_eliminateDeficit_allowSpokePaused() (gas: 429639)
[PASS] test_eliminateDeficit_fuzz_revertsWith_ArithmeticUnderflow_CallerSpokeNoFunds(uint256) (runs: 5000, μ: 343589, ~: 343589)
[PASS] test_eliminateDeficit_fuzz_revertsWith_callerSpokeNotActive(address) (runs: 5000, μ: 28908, ~: 28908)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_ZeroAmountNoDeficit() (gas: 20068)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_ZeroAmountWithDeficit() (gas: 340599)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 17.32s (17.30s CPU time)

Ran 6 tests for tests/unit/Hub/Hub.MintFeeShares.t.sol:HubMintFeeSharesTest
[PASS] test_mintFeeShares() (gas: 315081)
[PASS] test_mintFeeShares_noFees() (gas: 370676)
[PASS] test_mintFeeShares_noShares() (gas: 301714)
[PASS] test_mintFeeShares_revertsWith_AccessManagedUnauthorized() (gas: 25113)
[PASS] test_mintFeeShares_revertsWith_AssetNotListed() (gas: 27900)
[PASS] test_mintFeeShares_revertsWith_SpokeNotActive() (gas: 246152)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 25.05ms (4.42ms CPU time)

Ran 23 tests for tests/unit/AssetInterestRateStrategy.t.sol:AssetInterestRateStrategyTest
[PASS] test_calculateInterestRate_AtKinkPoint() (gas: 24686)
Logs:
  Bound result 2000
  Bound result 778565440757296803935461404101

[PASS] test_calculateInterestRate_AtMaxUtilization() (gas: 24958)
Logs:
  Bound result 10000
  Bound result 778565440757296803935461404101

[PASS] test_calculateInterestRate_LeftToKinkPoint(uint256) (runs: 5000, μ: 24547, ~: 24690)
[PASS] test_calculateInterestRate_RightToKinkPoint(uint256) (runs: 5000, μ: 25645, ~: 25690)
[PASS] test_calculateInterestRate_ZeroDebtZeroLiquidity() (gas: 18944)
Logs:
  Bound result 0

[PASS] test_calculateInterestRate_fuzz_ZeroDebt(uint256) (runs: 5000, μ: 19188, ~: 18950)
[PASS] test_calculateInterestRate_revertsWith_InterestRateDataNotSet() (gas: 11361)
[PASS] test_deploy_revertsWith_InvalidAddress() (gas: 36318)
[PASS] test_getBaseVariableBorrowRate() (gas: 14864)
[PASS] test_getInterestRateData() (gas: 19653)
[PASS] test_getMaxVariableBorrowRate() (gas: 15312)
[PASS] test_getOptimalUsageRatio() (gas: 14735)
[PASS] test_getVariableRateSlope1() (gas: 14810)
[PASS] test_getVariableRateSlope2() (gas: 14877)
[PASS] test_maxBorrowRate() (gas: 8431)
[PASS] test_maxOptimalRatio() (gas: 8431)
[PASS] test_minOptimalRatio() (gas: 8440)
[PASS] test_setInterestRateData() (gas: 69812)
[PASS] test_setInterestRateData_revertsWith_InvalidMaxRate() (gas: 42072)
[PASS] test_setInterestRateData_revertsWith_InvalidOptimalUsageRatio() (gas: 43120)
[PASS] test_setInterestRateData_revertsWith_InvalidRateData() (gas: 35395)
[PASS] test_setInterestRateData_revertsWith_OnlyHub() (gas: 23786)
[PASS] test_setInterestRateData_revertsWith_Slope2MustBeGteSlope1() (gas: 37980)
Suite result: ok. 23 passed; 0 failed; 0 skipped; finished in 192.82s (193.00s CPU time)

Ran 9 tests for tests/gas/Hub.Operations.gas.t.sol:HubOperations_Gas_Tests
[PASS] test_add() (gas: 273543)
[PASS] test_deficit() (gas: 1181399)
[PASS] test_draw() (gas: 423925)
[PASS] test_mintFeeShares() (gas: 508380)
[PASS] test_payFee_transferShares() (gas: 975461)
[PASS] test_refreshPremium() (gas: 636657)
[PASS] test_remove() (gas: 314977)
[PASS] test_restore() (gas: 891946)
[PASS] test_restore_with_transfer() (gas: 892614)
Suite result: ok. 9 passed; 0 failed; 0 skipped; finished in 41.24ms (7.66ms CPU time)

Ran 5 tests for tests/unit/Spoke/Spoke.AccrueLiquidityFee.EdgeCases.t.sol:SpokeAccrueLiquidityFeeEdgeCasesTest
[PASS] test_accrueLiquidityFee_fuzz_maxLiquidityFee_with_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 540828, ~: 541010)
[PASS] test_accrueLiquidityFee_fuzz_maxLiquidityFee_with_premium_multiple_users(uint256,uint256,uint256,uint256,uint256) (runs: 5000, μ: 792458, ~: 792511)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_multi_spoke() (gas: 648006633)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_multi_user() (gas: 260827203)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_with_premium() (gas: 541178)
Logs:
  Bound result 500000000000000000000
  Bound result 5000
  Bound result 34560000
  Bound result 2

Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 20.04s (30.56s CPU time)

Ran 6 tests for tests/unit/Hub/Hub.PayFee.t.sol:HubPayFeeTest
[PASS] test_payFee_fuzz(uint256,uint256) (runs: 5000, μ: 708176, ~: 708306)
[PASS] test_payFee_fuzz_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 708644, ~: 709021)
[PASS] test_payFee_revertsWith_InvalidShares() (gas: 20137)
[PASS] test_payFee_revertsWith_SpokeNotActive() (gas: 59766)
[PASS] test_payFee_revertsWith_underflow_added_shares_exceeded() (gas: 138907)
[PASS] test_payFee_revertsWith_underflow_added_shares_exceeded_with_interest() (gas: 653253)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 26.03s (39.09s CPU time)

Ran 7 tests for tests/unit/Spoke/Spoke.AccrueLiquidityFee.t.sol:SpokeAccrueLiquidityFeeTest
[PASS] test_accrueLiquidityFee() (gas: 882648)
[PASS] test_accrueLiquidityFee_NoActionTaken() (gas: 120065)
[PASS] test_accrueLiquidityFee_NoInterest_OnlySupply(uint40) (runs: 5000, μ: 247272, ~: 247256)
[PASS] test_accrueLiquidityFee_exact() (gas: 889402)
[PASS] test_accrueLiquidityFee_fuzz_BorrowAmountAndSkipTime(uint256,uint40) (runs: 5000, μ: 959717, ~: 982353)
[PASS] test_accrueLiquidityFee_maxLiquidityFee() (gas: 547052)
[PASS] test_accrueLiquidityFee_setUsingAsCollateral() (gas: 901613)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 21.75s (39.84s CPU time)

Ran 10 tests for tests/unit/Hub/Hub.Reclaim.t.sol:HubReclaimTest
[PASS] test_reclaim() (gas: 680835)
Logs:
  Bound result 1000000000000000000000
  Bound result 500000000000000000000
  Bound result 200000000000000000000

[PASS] test_reclaim_fullAmount() (gas: 661612)
[PASS] test_reclaim_fuzz(uint256,uint256,uint256) (runs: 5000, μ: 682634, ~: 681832)
[PASS] test_reclaim_multipleSweepsAndReclaims() (gas: 789909)
[PASS] test_reclaim_revertsWith_AssetNotListed() (gas: 12439)
[PASS] test_reclaim_revertsWith_InvalidAmount_zero() (gas: 93203)
[PASS] test_reclaim_revertsWith_OnlyReinvestmentController(address) (runs: 5000, μ: 94068, ~: 94068)
[PASS] test_reclaim_revertsWith_OnlyReinvestmentController_init() (gas: 40003)
[PASS] test_reclaim_revertsWith_underflow_exceedsSwept() (gas: 98666)
[PASS] test_reclaim_revertsWith_underflow_exceedsSwept_afterSweep() (gas: 461734)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 15.33s (16.99s CPU time)

Ran 12 tests for tests/unit/Hub/Hub.RefreshPremium.t.sol:HubRefreshPremiumTest
[PASS] test_refreshPremium_emitsEvent() (gas: 259520)
[PASS] test_refreshPremium_fuzz_positiveDeltas(uint256,int256,int256) (runs: 5000, μ: 468068, ~: 472513)
[PASS] test_refreshPremium_fuzz_withAccrual(uint256,uint256,uint256,uint256) (runs: 5000, μ: 536123, ~: 542886)
[PASS] test_refreshPremium_maxRiskPremiumThreshold() (gas: 896942)
[PASS] test_refreshPremium_negativeDeltas(uint256) (runs: 5000, μ: 461506, ~: 461527)
[PASS] test_refreshPremium_negativeDeltas_withAccrual(uint256) (runs: 5000, μ: 534484, ~: 534715)
[PASS] test_refreshPremium_pausedSpokesAllowed() (gas: 120629)
[PASS] test_refreshPremium_revertsWith_InvalidPremiumChange_NonZeroRestoredPremiumRay() (gas: 857131)
[PASS] test_refreshPremium_revertsWith_InvalidPremiumChange_RiskPremiumThresholdExceeded_DecreasingPremium() (gas: 875100)
[PASS] test_refreshPremium_revertsWith_SpokeNotActive() (gas: 57846)
[PASS] test_refreshPremium_riskPremiumThreshold() (gas: 922438)
[PASS] test_refreshPremium_spokePremiumUpdateIsContained() (gas: 710889)
Suite result: ok. 12 passed; 0 failed; 0 skipped; finished in 23.59s (35.32s CPU time)

Ran 15 tests for tests/unit/Hub/Hub.Remove.t.sol:HubRemoveTest
[PASS] test_remove() (gas: 210665)
Logs:
  Bound result 2
  Bound result 100000000000000000000

[PASS] test_remove_all_with_interest() (gas: 377919)
[PASS] test_remove_fuzz(uint256,uint256) (runs: 5000, μ: 209217, ~: 209034)
[PASS] test_remove_fuzz_all_liquidity_with_interest(uint256,uint256) (runs: 5000, μ: 429845, ~: 430159)
[PASS] test_remove_fuzz_multi_spoke(uint256,uint256) (runs: 5000, μ: 293876, ~: 294021)
[PASS] test_remove_fuzz_multi_spoke_with_interest(uint256,uint256,uint256,uint256) (runs: 5000, μ: 433372, ~: 433926)
[PASS] test_remove_revertsWith_InsufficientLiquidity() (gas: 160467)
[PASS] test_remove_revertsWith_InsufficientLiquidity_exceeding_added_amount() (gas: 148158)
[PASS] test_remove_revertsWith_InsufficientLiquidity_zero_added() (gas: 20745)
[PASS] test_remove_revertsWith_InvalidAddress() (gas: 15718)
[PASS] test_remove_revertsWith_InvalidAmount() (gas: 17819)
[PASS] test_remove_revertsWith_SpokeNotActive() (gas: 59890)
[PASS] test_remove_revertsWith_SpokePaused() (gas: 59996)
[PASS] test_remove_revertsWith_underflow_exceeding_added_amount() (gas: 188116)
[PASS] test_remove_revertsWtih_underflow_one_extra_wei() (gas: 372890)
Suite result: ok. 15 passed; 0 failed; 0 skipped; finished in 33.29s (58.81s CPU time)

Ran 8 tests for tests/unit/Spoke/Spoke.Repay.Scenario.t.sol:SpokeRepayScenarioTest
[PASS] test_fuzz_repay_borrow_twice_repay_twice((uint256,uint256,uint256,uint40),(uint256,uint256,uint256,uint40)) (runs: 5000, μ: 1214314, ~: 1219451)
[PASS] test_fuzz_repay_multiple_users_repay_same_reserve((uint256,uint256,uint256,uint256,uint256,uint256,address),(uint256,uint256,uint256,uint256,uint256,uint256,address),(uint256,uint256,uint256,uint256,uint256,uint256,address),uint256) (runs: 5000, μ: 2026662, ~: 1996638)
[PASS] test_repay_fuzz_multiple_users_multiple_assets(((uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),address),((uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),address),((uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),address),uint40) (runs: 5000, μ: 6004678, ~: 6004986)
[PASS] test_repay_fuzz_two_users_multiple_assets(((uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),address),((uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),address),uint40) (runs: 5000, μ: 4255762, ~: 4255969)
[PASS] test_repay_partial_then_max() (gas: 684373)
[PASS] test_repay_round_trip_borrow_repay(uint256,uint256,uint40,address,uint256) (runs: 5000, μ: 868190, ~: 871204)
[PASS] test_repay_round_trip_repay_borrow(uint256,uint256,uint256,uint40,address,uint256) (runs: 5000, μ: 954018, ~: 963524)
[PASS] test_repay_two_users_repay_same_reserve((uint256,uint256,uint256,uint256,uint256,uint256,address),(uint256,uint256,uint256,uint256,uint256,uint256,address),uint256) (runs: 5000, μ: 1462569, ~: 1492504)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 326.80s (326.78s CPU time)

Ran 2 tests for tests/unit/Spoke/Spoke.Repay.Validation.t.sol:SpokeRepayValidationTest
[PASS] test_repay_revertsWith_ReserveNotListed() (gas: 21908)
[PASS] test_repay_revertsWith_ReservePaused() (gas: 64866)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 24.80ms (375.60µs CPU time)

Ran 23 tests for tests/unit/Hub/Hub.Restore.t.sol:HubRestoreTest
[PASS] test_restore_full_amount_with_interest() (gas: 366906)
Logs:
  Bound result 1000000000000000000000
  Bound result 500000000000000000000
  Bound result 31536000

[PASS] test_restore_full_amount_with_interest_and_premium() (gas: 677542)
Logs:
  Bound result 100000000000000000000
  Bound result 50000000000000000000
  Bound result 31536000
  Bound result 1

[PASS] test_restore_fuzz_full_amount_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 368201, ~: 368305)
[PASS] test_restore_fuzz_full_amount_with_interest_and_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 667597, ~: 679493)
[PASS] test_restore_fuzz_revertsWith_SurplusDrawnRestored_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 248067, ~: 249307)
[PASS] test_restore_fuzz_revertsWith_SurplusDrawnRestored_with_interest_and_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 639815, ~: 640030)
[PASS] test_restore_one_share_delta_increase_revertsWith_InvalidPremiumChange() (gas: 214533)
[PASS] test_restore_partial_drawn() (gas: 330538)
[PASS] test_restore_partial_same_block() (gas: 326324)
[PASS] test_restore_premiumDeltas_twoWeiIncrease_realizedDelta() (gas: 236238)
[PASS] test_restore_revertsWith_InsufficientTransferred() (gas: 258503)
[PASS] test_restore_revertsWith_InvalidAmount_zero() (gas: 53477)
[PASS] test_restore_revertsWith_InvalidPremiumChange_premiumIncrease() (gas: 221685)
[PASS] test_restore_revertsWith_InvalidPremiumChange_premiumSharesIncrease() (gas: 221729)
[PASS] test_restore_revertsWith_SpokeNotActive_whenPaused() (gas: 166337)
[PASS] test_restore_revertsWith_SpokePaused() (gas: 93536)
[PASS] test_restore_revertsWith_SurplusDrawnRestored() (gas: 364815)
[PASS] test_restore_revertsWith_SurplusDrawnRestored_with_interest() (gas: 247883)
Logs:
  Bound result 100000000000000000000
  Bound result 50000000000000000000
  Bound result 15768000

[PASS] test_restore_revertsWith_SurplusDrawnRestored_with_interest_and_premium() (gas: 638102)
Logs:
  Bound result 100000000000000000000
  Bound result 50000000000000000000
  Bound result 31536000
  Bound result 1

[PASS] test_restore_revertsWith_SurplusPremiumRayRestored() (gas: 534440)
[PASS] test_restore_revertsWith_underflow_offsetIncrease() (gas: 232925)
[PASS] test_restore_tooMuchDrawn_revertsWith_SurplusDrawnRestored() (gas: 221898)
[PASS] test_restore_when_asset_frozen() (gas: 428614)
Suite result: ok. 23 passed; 0 failed; 0 skipped; finished in 20.60s (20.58s CPU time)

Ran 1 test for tests/unit/Hub/Hub.Rounding.t.sol:HubRoundingTest
[PASS] test_sharePriceWithMultipleDonations() (gas: 679058780)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 3.42s (3.40s CPU time)

Ran 4 tests for tests/unit/Hub/Hub.Skim.t.sol:HubSkimTest
[PASS] test_skimAdd_fuzz_donationAfterAdd(uint256,uint256,uint256) (runs: 5000, μ: 228305, ~: 228298)
[PASS] test_skimAdd_fuzz_donationBeforeAdd(uint256,uint256,uint256) (runs: 5000, μ: 228359, ~: 228352)
[PASS] test_skimAdd_fuzz_wrongSpokeTransfer(uint256,uint256,uint256) (runs: 5000, μ: 217207, ~: 217154)
[PASS] test_skimRestore_fuzz_liquidityDonation(uint256,uint256,uint256) (runs: 5000, μ: 276280, ~: 277893)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 28.19s (28.16s CPU time)

Ran 10 tests for tests/unit/Hub/Hub.SpokeConfig.t.sol:HubSpokeConfigTest
[PASS] test_add_active_paused_scenarios() (gas: 294616)
[PASS] test_draw_active_paused_scenarios() (gas: 295045)
[PASS] test_eliminateDeficit_active_paused_scenarios() (gas: 652511)
[PASS] test_mintFeeShares_active_paused_scenarios() (gas: 858366)
[PASS] test_payFeeShares_active_paused_scenarios() (gas: 348949)
[PASS] test_refreshPremium_active_paused_scenarios() (gas: 260812)
[PASS] test_remove_active_paused_scenarios() (gas: 309846)
[PASS] test_reportDeficit_active_paused_scenarios() (gas: 443127)
[PASS] test_restore_active_paused_scenarios() (gas: 349877)
[PASS] test_transferShares_fuzz_active_paused_scenarios(bool,bool,bool,bool) (runs: 5000, μ: 209717, ~: 209664)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 4.27s (4.25s CPU time)

Ran 8 tests for tests/unit/Hub/Hub.Sweep.t.sol:HubSweepTest
[PASS] test_sweep() (gas: 486514)
Logs:
  Bound result 1000000000000000000000
  Bound result 1000000000000000000000

[PASS] test_sweep_does_not_impact_utilization(uint256,uint256) (runs: 5000, μ: 635532, ~: 636947)
[PASS] test_sweep_fuzz(uint256,uint256) (runs: 5000, μ: 487027, ~: 487036)
[PASS] test_sweep_revertsWith_AssetNotListed() (gas: 12406)
[PASS] test_sweep_revertsWith_InsufficientLiquidity() (gas: 222401)
[PASS] test_sweep_revertsWith_InvalidAmount() (gas: 104297)
[PASS] test_sweep_revertsWith_OnlyReinvestmentController(address) (runs: 5000, μ: 94790, ~: 94790)
[PASS] test_sweep_revertsWith_OnlyReinvestmentController_init() (gas: 40016)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 19.40s (19.38s CPU time)

Ran 7 tests for tests/unit/Hub/Hub.TransferShares.t.sol:HubTransferSharesTest
[PASS] test_transferShares() (gas: 188879)
Logs:
  Bound result 1000000000000000000000
  Bound result 1000000000000000000000

[PASS] test_transferShares_fuzz(uint256,uint256) (runs: 5000, μ: 192241, ~: 192464)
[PASS] test_transferShares_fuzz_revertsWith_underflow_spoke_added_shares_exceeded(uint256) (runs: 5000, μ: 151664, ~: 151383)
[PASS] test_transferShares_revertsWith_AddCapExceeded() (gas: 195046)
[PASS] test_transferShares_revertsWith_SpokeNotActive() (gas: 176599)
[PASS] test_transferShares_revertsWith_SpokePaused() (gas: 178958)
[PASS] test_transferShares_zeroShares_revertsWith_InvalidShares() (gas: 22457)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 7.53s (7.52s CPU time)

Ran 17 tests for tests/unit/Spoke/Spoke.Borrow.HealthFactor.t.sol:SpokeBorrowHealthFactorTest
[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_collateral_price_drop(uint256,uint256) (runs: 5000, μ: 888418, ~: 888419)
[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_colls(uint256,uint256) (runs: 5000, μ: 856751, ~: 858085)
[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_colls_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 894198, ~: 895343)
[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_debts(uint256,uint256) (runs: 5000, μ: 1096004, ~: 1096120)
[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_debts_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 1136896, ~: 1136766)
[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_with_interest(uint256,uint256) (runs: 5000, μ: 674066, ~: 674370)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold() (gas: 640966)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_collateral_price_drop_weth() (gas: 882500)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls() (gas: 851683)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_dai() (gas: 1103546)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_weth() (gas: 1103590)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_with_interest() (gas: 890587)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_debts() (gas: 1089164)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_debts_with_interest() (gas: 1129539)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_with_interest() (gas: 668958)
[PASS] test_fuzz_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_dai(uint256,uint256,uint256) (runs: 5000, μ: 1106780, ~: 1108348)
[PASS] test_fuzz_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_weth(uint256,uint256,uint256) (runs: 5000, μ: 1107721, ~: 1108370)
Suite result: ok. 17 passed; 0 failed; 0 skipped; finished in 135.74s (135.71s CPU time)

Ran 6 tests for tests/unit/Hub/HubAccrueInterest.t.sol:HubAccrueInterestTest
[PASS] test_accrueInterest_NoActionTaken() (gas: 43656)
[PASS] test_accrueInterest_NoInterest_NoDebt(uint40) (runs: 5000, μ: 401944, ~: 401854)
[PASS] test_accrueInterest_NoInterest_OnlyAdd(uint40) (runs: 5000, μ: 210913, ~: 210858)
[PASS] test_accrueInterest_fuzz_BorrowAmountAndElapsed(uint256,uint40) (runs: 5000, μ: 276623, ~: 276266)
[PASS] test_accrueInterest_fuzz_BorrowAmountRateAndElapsed(uint256,uint256,uint40) (runs: 5000, μ: 402351, ~: 402132)
[PASS] test_accrueInterest_fuzz_BorrowAndWait(uint40) (runs: 5000, μ: 275373, ~: 275283)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 28.12s (28.10s CPU time)

Ran 7 tests for tests/unit/Hub/Hub.ReportDeficit.t.sol:HubReportDeficitTest
[PASS] test_reportDeficit_fuzz_revertsWith_SurplusDrawnDeficitReported(uint256) (runs: 5000, μ: 221794, ~: 221521)
[PASS] test_reportDeficit_fuzz_revertsWith_SurplusPremiumRayDeficitReported(uint256) (runs: 5000, μ: 223366, ~: 223093)
[PASS] test_reportDeficit_fuzz_with_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 676768, ~: 677711)
[PASS] test_reportDeficit_paused() (gas: 271351)
[PASS] test_reportDeficit_revertsWith_InvalidAmount() (gas: 24122)
[PASS] test_reportDeficit_revertsWith_SpokeNotActive(address) (runs: 5000, μ: 32527, ~: 32527)
[PASS] test_reportDeficit_with_premium() (gas: 676264)
Logs:
  Bound result 10000000000
  Bound result 31536000
  Bound result 5000000000
  Bound result 0

Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 130.18s (145.78s CPU time)

Ran 3 tests for tests/unit/Hub/Hub.Rescue.t.sol:HubRescueTest
[PASS] test_cannot_rescue_liquidity_fee_reverts_with_InsufficientTransferred() (gas: 279900)
[PASS] test_rescue_fuzz_with_interest(uint256,uint256) (runs: 5000, μ: 526154, ~: 526142)
[PASS] test_rescue_scenario_fuzz(uint256) (runs: 5000, μ: 462921, ~: 462720)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 19.89s (29.28s CPU time)

Ran 7 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.DebtToTargetHealthFactor.t.sol:LiquidationLogicDebtToTargetHealthFactorTest
[PASS] test_calculateDebtToTargetHealthFactor_HealthFactorEqualsTargetHealthFactor((uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 23057, ~: 23016)
[PASS] test_calculateDebtToTargetHealthFactor_NoPrecisionLoss() (gas: 25208)
[PASS] test_calculateDebtToTargetHealthFactor_PrecisionLoss() (gas: 15209)
[PASS] test_calculateDebtToTargetHealthFactor_UnitPrice() (gas: 25141)
[PASS] test_calculateDebtToTargetHealthFactor_fuzz_NoRevert((uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 20118, ~: 20077)
[PASS] test_calculateDebtToTargetHealthFactor_fuzz_revertsWith_DivisionByZero_ZeroAssetPrice((uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 22817, ~: 22776)
[PASS] test_calculateDebtToTargetHealthFactor_revertsWith_ArithmeticError_TargetHealthFactorLessThanHealthFactor((uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 22900, ~: 22859)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 2.81s (2.79s CPU time)

Ran 16 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.EvaluateDeficit.t.sol:LiquidationLogicEvaluateDeficitTest
[PASS] test_evaluateDeficit_CRE_SCCM_DRE_BRCM() (gas: 9012)
[PASS] test_evaluateDeficit_CRE_SCCM_DRE_BRCO() (gas: 8980)
[PASS] test_evaluateDeficit_CRE_SCCM_DRN_BRCM() (gas: 9001)
[PASS] test_evaluateDeficit_CRE_SCCM_DRN_BRCO() (gas: 8968)
[PASS] test_evaluateDeficit_CRE_SCCO_DRE_BRCM() (gas: 8994)
[PASS] test_evaluateDeficit_CRE_SCCO_DRE_BRCO() (gas: 9061)
[PASS] test_evaluateDeficit_CRE_SCCO_DRN_BRCM() (gas: 9026)
[PASS] test_evaluateDeficit_CRE_SCCO_DRN_BRCO() (gas: 9014)
[PASS] test_evaluateDeficit_CRN_SCCM_DRE_BRCM() (gas: 9014)
[PASS] test_evaluateDeficit_CRN_SCCM_DRE_BRCO() (gas: 9003)
[PASS] test_evaluateDeficit_CRN_SCCM_DRN_BRCM() (gas: 8937)
[PASS] test_evaluateDeficit_CRN_SCCM_DRN_BRCO() (gas: 8970)
[PASS] test_evaluateDeficit_CRN_SCCO_DRE_BRCM() (gas: 8947)
[PASS] test_evaluateDeficit_CRN_SCCO_DRE_BRCO() (gas: 9004)
[PASS] test_evaluateDeficit_CRN_SCCO_DRN_BRCM() (gas: 8955)
[PASS] test_evaluateDeficit_CRN_SCCO_DRN_BRCO() (gas: 9033)
Suite result: ok. 16 passed; 0 failed; 0 skipped; finished in 21.11ms (1.05ms CPU time)

Ran 5 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidateCollateral.t.sol:LiquidationLogicLiquidateCollateralTest
[PASS] test_liquidateCollateral_fuzz(uint256,uint256) (runs: 5000, μ: 268311, ~: 269280)
[PASS] test_liquidateCollateral_fuzz_CollateralToLiquidatorIsZero(uint256) (runs: 5000, μ: 110216, ~: 110942)
[PASS] test_liquidateCollateral_fuzz_receiveShares_sharesToLiquidator(uint256,uint256) (runs: 5000, μ: 754963, ~: 756261)
[PASS] test_liquidateCollateral_fuzz_revertsWith_ArithmeticUnderflow(uint256,uint256) (runs: 5000, μ: 100455, ~: 100270)
[PASS] test_liquidateCollateral_receiveShares_sharesToLiquidatorIsZero() (gas: 741771)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 13.84s (13.82s CPU time)

Ran 60 tests for tests/unit/HubConfigurator.t.sol:HubConfiguratorTest
[PASS] test_addAsset_fuzz(bool,address,uint8,address,uint256,uint16,uint32,uint32,uint32) (runs: 5000, μ: 968967, ~: 969535)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAssetDecimals(bool,address,uint8,address,uint256,address) (runs: 5000, μ: 57784, ~: 57713)
[PASS] test_addAsset_fuzz_revertsWith_OwnableUnauthorizedAccount(address) (runs: 5000, μ: 31175, ~: 31175)
[PASS] test_addAsset_revertsWith_InvalidAddress_irStrategy() (gas: 50979)
[PASS] test_addAsset_revertsWith_InvalidAddress_underlying() (gas: 50878)
[PASS] test_addAsset_revertsWith_InvalidLiquidityFee() (gas: 872676)
[PASS] test_addAsset_reverts_invalidIrData() (gas: 47009)
[PASS] test_addSpoke() (gas: 126387)
[PASS] test_addSpokeToAssets() (gas: 222897)
[PASS] test_addSpokeToAssets_revertsWith_MismatchedConfigs() (gas: 24780)
[PASS] test_addSpokeToAssets_revertsWith_OwnableUnauthorizedAccount() (gas: 17127)
[PASS] test_addSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 16904)
[PASS] test_deactivateAsset() (gas: 159149)
[PASS] test_deactivateAsset_revertsWith_OwnableUnauthorizedAccount() (gas: 17944)
[PASS] test_deactivateSpoke() (gas: 156743)
[PASS] test_deactivateSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 18038)
[PASS] test_freezeAsset() (gas: 233782)
[PASS] test_freezeAsset_revertsWith_OwnableUnauthorizedAccount() (gas: 18007)
[PASS] test_freezeSpoke() (gas: 249960)
[PASS] test_freezeSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 18016)
[PASS] test_pauseAsset() (gas: 159137)
[PASS] test_pauseAsset_revertsWith_OwnableUnauthorizedAccount() (gas: 17964)
[PASS] test_pauseSpoke() (gas: 156712)
[PASS] test_pauseSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 18015)
[PASS] test_updateFeeConfig_Scenario() (gas: 336247)
Logs:
  Bound result 0
  Bound result 1800
  Bound result 0
  Bound result 400
  Bound result 0
  Bound result 0

[PASS] test_updateFeeConfig_fuzz(uint256,uint16,address) (runs: 5000, μ: 186068, ~: 186354)
[PASS] test_updateFeeConfig_fuzz_revertsWith_OwnableUnauthorizedAccount(address) (runs: 5000, μ: 17771, ~: 17771)
[PASS] test_updateFeeConfig_revertsWith_InvalidAddress_spoke() (gas: 50220)
[PASS] test_updateFeeConfig_revertsWith_InvalidLiquidityFee() (gas: 52359)
[PASS] test_updateFeeReceiver_Scenario() (gas: 214825)
[PASS] test_updateFeeReceiver_WithdrawFromOldSpoke() (gas: 1041749)
[PASS] test_updateFeeReceiver_correctAccruals() (gas: 1077268)
[PASS] test_updateFeeReceiver_fuzz(address) (runs: 5000, μ: 180111, ~: 180129)
[PASS] test_updateFeeReceiver_fuzz_revertsWith_OwnableUnauthorizedAccount(address) (runs: 5000, μ: 17292, ~: 17292)
[PASS] test_updateFeeReceiver_revertsWith_InvalidAddress_spoke() (gas: 54801)
[PASS] test_updateFeeReceiver_revertsWith_SpokeAlreadyListed() (gas: 86380)
[PASS] test_updateInterestRateData() (gas: 74133)
[PASS] test_updateInterestRateData_revertsWith_OwnableUnauthorizedAccount() (gas: 19194)
[PASS] test_updateInterestRateStrategy() (gas: 93923)
[PASS] test_updateInterestRateStrategy_fuzz_revertsWith_OwnableUnauthorizedAccount(address) (runs: 5000, μ: 28677, ~: 28677)
[PASS] test_updateInterestRateStrategy_revertsWith_InterestRateStrategyReverts() (gas: 76767)
[PASS] test_updateInterestRateStrategy_revertsWith_InvalidAddress_irStrategy() (gas: 66444)
[PASS] test_updateInterestRateStrategy_revertsWith_InvalidInterestRateStrategy() (gas: 66960)
[PASS] test_updateLiquidityFee_fuzz(uint256,uint16) (runs: 5000, μ: 90658, ~: 92319)
[PASS] test_updateLiquidityFee_revertsWith_InvalidLiquidityFee() (gas: 54832)
[PASS] test_updateLiquidityFee_revertsWith_OwnableUnauthorizedAccount() (gas: 16698)
[PASS] test_updateReinvestmentController() (gas: 101877)
[PASS] test_updateReinvestmentController_fuzz_revertsWith_OwnableUnauthorizedAccount(address) (runs: 5000, μ: 17291, ~: 17291)
[PASS] test_updateSpokeActive() (gas: 84484)
[PASS] test_updateSpokeActive_revertsWith_OwnableUnauthorizedAccount() (gas: 20241)
[PASS] test_updateSpokeCaps() (gas: 64549)
[PASS] test_updateSpokeCaps_revertsWith_OwnableUnauthorizedAccount() (gas: 20238)
[PASS] test_updateSpokeDrawCap() (gas: 64380)
[PASS] test_updateSpokeDrawCap_revertsWith_OwnableUnauthorizedAccount() (gas: 20179)
[PASS] test_updateSpokePaused() (gas: 87508)
[PASS] test_updateSpokePaused_revertsWith_OwnableUnauthorizedAccount() (gas: 20308)
[PASS] test_updateSpokeRiskPremiumThreshold() (gas: 64322)
[PASS] test_updateSpokeRiskPremiumThreshold_revertsWith_OwnableUnauthorizedAccount() (gas: 20246)
[PASS] test_updateSpokeSupplyCap() (gas: 64326)
[PASS] test_updateSpokeSupplyCap_revertsWith_OwnableUnauthorizedAccount() (gas: 20213)
Suite result: ok. 60 passed; 0 failed; 0 skipped; finished in 27.18s (32.82s CPU time)

Ran 16 tests for tests/unit/Spoke/Spoke.Repay.t.sol:SpokeRepayTest
[PASS] test_fuzz_amounts_repay_only_premium(uint256,uint256,uint40) (runs: 5000, μ: 873149, ~: 875341)
[PASS] test_fuzz_repay_amounts_only_interest(uint256,uint256,uint40) (runs: 5000, μ: 881769, ~: 886827)
[PASS] test_fuzz_repay_only_premium(uint256,uint40) (runs: 5000, μ: 754867, ~: 754899)
[PASS] test_fuzz_repay_same_block_fuzz_amounts(uint256,uint256) (runs: 5000, μ: 882832, ~: 893408)
[PASS] test_fuzz_repay_x_y_shares(uint256,uint40) (runs: 5000, μ: 619323, ~: 619465)
[PASS] test_repay() (gas: 698013)
[PASS] test_repay_all_with_accruals() (gas: 425838)
[PASS] test_repay_fuzz_amountsAndWait(uint256,uint256,uint40) (runs: 5000, μ: 925395, ~: 927510)
[PASS] test_repay_fuzz_amounts_base_debt(uint256,uint256,uint40) (runs: 5000, μ: 929774, ~: 942000)
[PASS] test_repay_fuzz_amounts_base_debt_no_premium(uint256,uint256,uint40) (runs: 5000, μ: 806804, ~: 816737)
[PASS] test_repay_fuzz_revertsWith_ERC20InsufficientBalance(uint256) (runs: 5000, μ: 556653, ~: 556751)
[PASS] test_repay_max() (gas: 599176)
[PASS] test_repay_multiple_reserves_fuzz_amountsAndWait(uint256,uint256,uint256,uint256,uint256,uint40) (runs: 5000, μ: 3306975, ~: 3312128)
[PASS] test_repay_only_interest() (gas: 720059)
[PASS] test_repay_revertsWith_ERC20InsufficientAllowance() (gas: 559010)
[PASS] test_repay_same_block() (gas: 677875)
Suite result: ok. 16 passed; 0 failed; 0 skipped; finished in 199.99s (199.97s CPU time)

Ran 5 tests for tests/unit/Spoke/Spoke.ReserveConfig.t.sol:SpokeReserveConfigTest
[PASS] test_borrow_fuzz_borrowable_paused_frozen_scenarios(bool,bool,bool) (runs: 5000, μ: 284134, ~: 258971)
[PASS] test_repay_fuzz_paused_scenarios(bool) (runs: 5000, μ: 562469, ~: 561128)
[PASS] test_setUsingAsCollateral_fuzz_paused_frozen_scenarios(bool) (runs: 5000, μ: 187251, ~: 187278)
[PASS] test_supply_paused_frozen_scenarios() (gas: 338359)
[PASS] test_withdraw_paused_scenarios() (gas: 301196)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 17.71s (17.69s CPU time)

Ran 9 tests for tests/unit/libraries/KeyValueList.t.sol:KeyValueListTest
[PASS] test_add_unique() (gas: 325391)
[PASS] test_fuzz_add(uint256,uint256) (runs: 5000, μ: 200291, ~: 201361)
[PASS] test_fuzz_add_unique(uint256,uint256) (runs: 5000, μ: 265804, ~: 267283)
[PASS] test_fuzz_get(uint256[]) (runs: 5000, μ: 413030, ~: 411058)
[PASS] test_fuzz_get_uninitialized(uint256[]) (runs: 5000, μ: 263153, ~: 252829)
[PASS] test_fuzz_get_uninitialized_sorted(uint256[]) (runs: 5000, μ: 204971, ~: 184864)
[PASS] test_fuzz_sortByKey(uint256[]) (runs: 5000, μ: 464335, ~: 453986)
[PASS] test_fuzz_sortByKey_length(uint256) (runs: 5000, μ: 230372, ~: 241359)
[PASS] test_fuzz_sortByKey_with_collision(uint256[]) (runs: 5000, μ: 547947, ~: 538374)
Suite result: ok. 9 passed; 0 failed; 0 skipped; finished in 72.45s (122.90s CPU time)

Ran 3 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.DebtToLiquidate.t.sol:LiquidationLogicDebtToLiquidateTest
[PASS] test_calculateDebtToLiquidate_fuzz((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 30635, ~: 30638)
[PASS] test_calculateDebtToLiquidate_fuzz_AmountAdjustedDueToDust((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 32366, ~: 32390)
[PASS] test_calculateDebtToLiquidate_fuzz_ImpossibleToAdjustForDust((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 34482, ~: 34396)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 3.38s (5.69s CPU time)

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidationBonus.t.sol:LiquidationLogicLiquidationBonusTest
[PASS] test_calculateLiquidationBonus_MinBonusDueToRounding() (gas: 9317)
[PASS] test_calculateLiquidationBonus_PartialBonus() (gas: 9338)
[PASS] test_calculateLiquidationBonus_fuzz_ConstantBonus(uint256,uint256,uint256,uint256) (runs: 5000, μ: 17323, ~: 17135)
[PASS] test_calculateLiquidationBonus_fuzz_MaxBonus(uint256,uint256,uint256,uint256) (runs: 5000, μ: 19611, ~: 19420)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 1.02s (997.35ms CPU time)

Ran 12 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.ValidateLiquidationCall.t.sol:LiquidationLogicValidateLiquidationCallTest
[PASS] test_validateLiquidationCall() (gas: 26157)
[PASS] test_validateLiquidationCall_revertsWith_CannotReceiveShares() (gas: 262562)
[PASS] test_validateLiquidationCall_revertsWith_CollateralCannotBeLiquidated() (gas: 46049)
[PASS] test_validateLiquidationCall_revertsWith_HealthFactorNotBelowThreshold() (gas: 32053)
[PASS] test_validateLiquidationCall_revertsWith_InvalidDebtToCover() (gas: 27026)
[PASS] test_validateLiquidationCall_revertsWith_ReserveNotBorrowed() (gas: 27145)
[PASS] test_validateLiquidationCall_revertsWith_ReserveNotEnabledAsCollateral_NotUsingAsCollateral() (gas: 27266)
[PASS] test_validateLiquidationCall_revertsWith_ReserveNotEnabledAsCollateral_ZeroCollateralFactor() (gas: 27282)
[PASS] test_validateLiquidationCall_revertsWith_ReserveNotSupplied() (gas: 27112)
[PASS] test_validateLiquidationCall_revertsWith_ReservePaused_CollateralPaused() (gas: 32175)
[PASS] test_validateLiquidationCall_revertsWith_ReservePaused_DebtPaused() (gas: 32175)
[PASS] test_validateLiquidationCall_revertsWith_SelfLiquidation() (gas: 33938)
Suite result: ok. 12 passed; 0 failed; 0 skipped; finished in 21.66ms (1.55ms CPU time)

Ran 27 tests for tests/unit/MathUtils.t.sol:MathUtilsTest
[PASS] test_add_edge_cases() (gas: 4854)
[PASS] test_add_negative_operand(uint256,int256) (runs: 5000, μ: 9258, ~: 9012)
[PASS] test_add_positive_operand(uint256,int256) (runs: 5000, μ: 4015, ~: 4010)
[PASS] test_calculateLinearInterest() (gas: 4445)
[PASS] test_calculateLinearInterest_add_edge() (gas: 5043)
[PASS] test_calculateLinearInterest_edge_cases() (gas: 16815)
Logs:
  Bound result 0
  Bound result 1
  Bound result 864000000
  Bound result 864000000

[PASS] test_calculateLinearInterest_reverts_on_past_timestamp(uint40) (runs: 5000, μ: 7706, ~: 7550)
[PASS] test_constants() (gas: 3167)
[PASS] test_fuzz_calculateLinearInterest(uint96,uint40,uint256) (runs: 5000, μ: 8752, ~: 8996)
[PASS] test_fuzz_mulDivDown(uint256,uint256,uint256) (runs: 5000, μ: 3577, ~: 3634)
[PASS] test_fuzz_mulDivUp(uint256,uint256,uint256) (runs: 5000, μ: 3660, ~: 3781)
[PASS] test_min(uint256,uint256) (runs: 5000, μ: 3338, ~: 3338)
[PASS] test_mulDivDown_NoRemainder() (gas: 3280)
[PASS] test_mulDivDown_RevertOnDivByZero() (gas: 3125)
[PASS] test_mulDivDown_RevertOnOverflow() (gas: 3181)
[PASS] test_mulDivDown_WithRemainder() (gas: 3325)
[PASS] test_mulDivDown_ZeroAOrB() (gas: 3768)
[PASS] test_mulDivUp_NoRemainder() (gas: 3306)
[PASS] test_mulDivUp_RevertOnDivByZero() (gas: 3102)
[PASS] test_mulDivUp_RevertOnOverflow() (gas: 3160)
[PASS] test_mulDivUp_WithRemainder() (gas: 3305)
[PASS] test_mulDivUp_ZeroAOrB() (gas: 3884)
[PASS] test_signedSub(uint256,uint256) (runs: 5000, μ: 8836, ~: 8783)
[PASS] test_signedSub_revertsWith_SafeCastOverflowedUintToInt(uint256) (runs: 5000, μ: 7767, ~: 7811)
[PASS] test_uncheckedAdd(uint256,uint256) (runs: 5000, μ: 3505, ~: 3497)
[PASS] test_uncheckedExp(uint256,uint256) (runs: 5000, μ: 12008, ~: 9309)
[PASS] test_uncheckedSub(uint256,uint256) (runs: 5000, μ: 3434, ~: 3352)
Suite result: ok. 27 passed; 0 failed; 0 skipped; finished in 1.87s (1.86s CPU time)

Ran 6 tests for tests/unit/Spoke/Spoke.Borrow.Scenario.t.sol:SpokeBorrowScenarioTest
[PASS] test_borrow_fuzz_multi_spoke_multi_reserves(uint256,uint256,uint256,uint256,uint256) (runs: 5000, μ: 2116131, ~: 2126345)
[PASS] test_borrow_fuzz_single_spoke_multi_reserves(uint256,uint256,uint256,uint256) (runs: 5000, μ: 2237204, ~: 2245356)
[PASS] test_borrow_fuzz_single_spoke_multi_reserves_multi_user(uint256,uint256,uint256,uint256) (runs: 5000, μ: 2669511, ~: 2678227)
[PASS] test_borrow_fuzz_skip_borrow(uint256,uint256,uint256) (runs: 5000, μ: 1044101, ~: 1044144)
[PASS] test_borrow_skip_borrow() (gas: 1043049)
Logs:
  Bound result 10000000000000000000
  Bound result 20000000000000000000
  Bound result 31536000

[PASS] test_userAccountData_does_not_include_zero_cf_collateral() (gas: 1165461)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 171.74s (171.72s CPU time)

Ran 14 tests for tests/unit/Spoke/Spoke.Borrow.Validation.t.sol:SpokeBorrowValidationTest
[PASS] test_borrow_fuzz_revertsWith_DrawCapExceeded(uint256,uint40) (runs: 5000, μ: 107379, ~: 107401)
[PASS] test_borrow_fuzz_revertsWith_DrawCapExceeded_due_to_interest(uint256) (runs: 5000, μ: 685505, ~: 685737)
[PASS] test_borrow_fuzz_revertsWith_InsufficientLiquidity(uint256,uint256) (runs: 5000, μ: 296683, ~: 296456)
[PASS] test_borrow_fuzz_revertsWith_InvalidAmount(uint256) (runs: 5000, μ: 32472, ~: 32526)
[PASS] test_borrow_fuzz_revertsWith_ReserveFrozen(uint256,uint256) (runs: 5000, μ: 71545, ~: 71336)
[PASS] test_borrow_fuzz_revertsWith_ReserveNotBorrowable(uint256,uint256) (runs: 5000, μ: 71665, ~: 71456)
[PASS] test_borrow_fuzz_revertsWith_ReserveNotListed(uint256,uint256) (runs: 5000, μ: 26135, ~: 25872)
[PASS] test_borrow_fuzz_revertsWith_ReservePaused(uint256,uint256) (runs: 5000, μ: 71497, ~: 71288)
[PASS] test_borrow_revertsWith_InsufficientLiquidity() (gas: 296323)
Logs:
  Bound result 10000000000000000000

[PASS] test_borrow_revertsWith_InvalidAmount() (gas: 34159)
Logs:
  Bound result 2

[PASS] test_borrow_revertsWith_ReserveFrozen() (gas: 72942)
Logs:
  Bound result 2
  Bound result 1

[PASS] test_borrow_revertsWith_ReserveNotBorrowable() (gas: 73038)
Logs:
  Bound result 2
  Bound result 1

[PASS] test_borrow_revertsWith_ReserveNotListed() (gas: 27200)
Logs:
  Bound result 1

[PASS] test_borrow_revertsWith_ReservePaused() (gas: 72936)
Logs:
  Bound result 2
  Bound result 1

Suite result: ok. 14 passed; 0 failed; 0 skipped; finished in 15.26s (15.24s CPU time)

Ran 32 tests for tests/unit/misc/NativeTokenGateway.t.sol:NativeTokenGatewayTest
[PASS] test_borrowNative() (gas: 666217)
Logs:
  Bound result 5000000000000000000

[PASS] test_borrowNative_fuzz(uint256) (runs: 5000, μ: 665437, ~: 666246)
[PASS] test_borrowNative_revertsWith_InvalidAmount() (gas: 32207)
[PASS] test_borrowNative_revertsWith_NotNativeWrappedAsset() (gas: 32290)
[PASS] test_borrowNative_revertsWith_SpokeNotRegistered() (gas: 25298)
[PASS] test_constructor() (gas: 1051071)
[PASS] test_constructor_revertsWith_InvalidAddress() (gas: 65404)
[PASS] test_fallback_revertsWith_UnsupportedAction() (gas: 17852)
[PASS] test_receive_revertsWith_UnsupportedAction() (gas: 17647)
[PASS] test_repayNative() (gas: 754043)
Logs:
  Bound result 5000000000000000000

[PASS] test_repayNative_excessAmount() (gas: 666009)
[PASS] test_repayNative_fuzz(uint256) (runs: 5000, μ: 748755, ~: 754363)
[PASS] test_repayNative_fuzz_withInterest(uint256,uint256) (runs: 5000, μ: 676714, ~: 672163)
[PASS] test_repayNative_revertsWith_InvalidAmount() (gas: 32565)
[PASS] test_repayNative_revertsWith_NativeAmountMismatch() (gas: 30659)
[PASS] test_repayNative_revertsWith_NotNativeWrappedAsset() (gas: 39262)
[PASS] test_repayNative_revertsWith_SpokeNotRegistered() (gas: 39286)
[PASS] test_supplyAndCollateralNative() (gas: 331966)
Logs:
  Bound result 100000000000000000000

[PASS] test_supplyAndCollateralNative_fuzz(uint256) (runs: 5000, μ: 332251, ~: 331972)
[PASS] test_supplyNative() (gas: 304356)
Logs:
  Bound result 100000000000000000000

[PASS] test_supplyNative_fuzz(uint256) (runs: 5000, μ: 304707, ~: 304428)
[PASS] test_supplyNative_revertsWith_InvalidAmount() (gas: 32530)
[PASS] test_supplyNative_revertsWith_NativeAmountMismatch() (gas: 30390)
[PASS] test_supplyNative_revertsWith_NotNativeWrappedAsset() (gas: 39225)
[PASS] test_supplyNative_revertsWith_SpokeNotRegistered() (gas: 39197)
[PASS] test_withdrawNative() (gas: 330531)
Logs:
  Bound result 100000000000000000000

[PASS] test_withdrawNative_fuzz(uint256) (runs: 5000, μ: 330017, ~: 330581)
[PASS] test_withdrawNative_fuzz_allBalance(uint256) (runs: 5000, μ: 268732, ~: 268533)
[PASS] test_withdrawNative_fuzz_allBalanceWithInterest(uint256,uint256) (runs: 5000, μ: 620780, ~: 620776)
[PASS] test_withdrawNative_revertsWith_InvalidAmount() (gas: 32293)
[PASS] test_withdrawNative_revertsWith_NotNativeWrappedAsset() (gas: 32245)
[PASS] test_withdrawNative_revertsWith_SpokeNotRegistered() (gas: 25408)
Suite result: ok. 32 passed; 0 failed; 0 skipped; finished in 65.21s (65.19s CPU time)

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidateDebt.t.sol:LiquidationLogicLiquidateDebtTest
[PASS] test_liquidateDebt_fuzz(uint256) (runs: 5000, μ: 233384, ~: 233384)
[PASS] test_liquidateDebt_revertsWith_ArithmeticUnderflow() (gas: 97214)
[PASS] test_liquidateDebt_revertsWith_InsufficientAllowance() (gas: 124641)
[PASS] test_liquidateDebt_revertsWith_InsufficientBalance() (gas: 182480)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 71.35s (71.32s CPU time)

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidateUser.t.sol:LiquidationLogicLiquidateUserTest
[PASS] test_liquidateUser() (gas: 368536)
[PASS] test_liquidateUser_revertsWith_InvalidDebtToCover() (gas: 76753)
[PASS] test_liquidateUser_revertsWith_MustNotLeaveDust_Collateral() (gas: 110465)
[PASS] test_liquidateUser_revertsWith_MustNotLeaveDust_Debt() (gas: 119743)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 26.79ms (1.49ms CPU time)

Ran 2 tests for tests/unit/Spoke/Spoke.Borrow.t.sol:SpokeBorrowTest
[PASS] test_borrow() (gas: 1075619)
[PASS] test_borrow_fuzz_amounts(uint256,uint256) (runs: 5000, μ: 1087491, ~: 1087571)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 27.81s (27.78s CPU time)

Ran 24 tests for tests/unit/Spoke/Spoke.Config.t.sol:SpokeConfigTest
[PASS] test_addReserve() (gas: 397278)
[PASS] test_addReserve_fuzz_revertsWith_AssetNotListed() (gas: 246015)
[PASS] test_addReserve_revertsWith_InvalidAddress_hub() (gas: 6055661)
[PASS] test_addReserve_revertsWith_InvalidAddress_oracle() (gas: 6092863)
[PASS] test_addReserve_revertsWith_InvalidAssetId() (gas: 33550)
[PASS] test_addReserve_revertsWith_ReserveExists() (gas: 376526)
[PASS] test_spoke_deploy() (gas: 4988454)
[PASS] test_spoke_deploy_revertsWith_InvalidOracleDecimals() (gas: 46514)
[PASS] test_spoke_deploy_reverts_on_InvalidConstructorInput() (gas: 43936)
[PASS] test_updateLiquidationConfig_fuzz_liqBonusConfig((uint128,uint64,uint16)) (runs: 5000, μ: 52050, ~: 52115)
[PASS] test_updateLiquidationConfig_fuzz_revertsWith_InvalidLiquidationConfig_healthFactorForMaxBonus((uint128,uint64,uint16)) (runs: 5000, μ: 37818, ~: 38055)
[PASS] test_updateLiquidationConfig_fuzz_revertsWith_InvalidLiquidationConfig_liquidationBonusFactor((uint128,uint64,uint16)) (runs: 5000, μ: 37515, ~: 37267)
[PASS] test_updateLiquidationConfig_fuzz_targetHealthFactor(uint128) (runs: 5000, μ: 46874, ~: 47176)
[PASS] test_updateLiquidationConfig_liqBonusConfig() (gas: 51074)
Logs:
  Bound result 900000000000000000
  Bound result 1000
  Bound result 1000000000000000000

[PASS] test_updateLiquidationConfig_revertsWith_InvalidLiquidationConfig_healthFactorForMaxBonus() (gas: 36568)
Logs:
  Bound result 1000000000000000000
  Bound result 1000
  Bound result 1000000000000000000

[PASS] test_updateLiquidationConfig_revertsWith_InvalidLiquidationConfig_liquidationBonusFactor() (gas: 36362)
Logs:
  Bound result 900000000000000000
  Bound result 10001
  Bound result 1000000000000000000

[PASS] test_updateLiquidationConfig_targetHealthFactor() (gas: 46481)
Logs:
  Bound result 1000000000000000001

[PASS] test_updateReserveConfig() (gas: 57192)
[PASS] test_updateReserveConfig_fuzz((uint24,bool,bool,bool,bool,bool)) (runs: 5000, μ: 58384, ~: 58223)
[PASS] test_updateReserveConfig_revertsWith_InvalidCollateralRisk() (gas: 40117)
[PASS] test_updateReserveConfig_revertsWith_ReserveNotListed() (gas: 36568)
[PASS] test_updateReservePriceSource() (gas: 240241)
[PASS] test_updateReservePriceSource_revertsWith_AccessManagedUnauthorized(address) (runs: 5000, μ: 31214, ~: 31214)
[PASS] test_updateReservePriceSource_revertsWith_ReserveNotListed() (gas: 34454)
Suite result: ok. 24 passed; 0 failed; 0 skipped; finished in 4.01s (3.99s CPU time)

Ran 8 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidationAmounts.t.sol:LiquidationLogicLiquidationAmountsTest
[PASS] test_calculateLiquidationAmounts_EnoughCollateral() (gas: 15487)
[PASS] test_calculateLiquidationAmounts_InsufficientCollateral() (gas: 15739)
[PASS] test_calculateLiquidationAmounts_fuzz_EnoughCollateral_CollateralDust((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 56979, ~: 56823)
[PASS] test_calculateLiquidationAmounts_fuzz_EnoughCollateral_NoCollateralDust((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 55988, ~: 55957)
[PASS] test_calculateLiquidationAmounts_fuzz_EnoughCollateral_NoDebtLeft((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 72591, ~: 72461)
[PASS] test_calculateLiquidationAmounts_fuzz_InsufficientCollateral((uint256,uint256...*[Comment body truncated]*


/// @inheritdoc IAccessManagerEnumerable
function getRoles(uint256 start, uint256 end) external view returns (uint64[] memory) {
uint256[] memory listedRoles = _rolesSet.values(start, end);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we not just return _rolesSet.values(start, end)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if yes, do we need this fn anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

roleIds are uint64 everywhere else, so I think better to return in the same uint64 format here


/// @dev Override AccessManager `_grantRole` function to track role members.
function _grantRole(
uint64 roleId,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if roleId is ADMIN_ROLE or PUBLIC_ROLE? No need to track ig

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will track the ADMIN_ROLE, and it's members, since the constructor does _grantRole(ADMIN_ROLE, initialAdmin, 0, 0)
The PUBLIC_ROLE is not track indeed, which is okay since by naming it's public, so defined by default and accepts all members.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you are right. ADMIN_ROLE is always being tracked.
PUBLIC_ROLE does not matter as all role-related functions will revert if they are triggered with this role id.
Exception is _setTargetFunctionRole, which allows PUBLIC_ROLE and the internal method _trackRoleTarget keeps track of all targets assigned to this role. Do not see any test case covering this aspect, can you add please?
Also, should we say in the roles getters that PUBLIC_ROLE is never returned?


/// @dev Override AccessManager `_setRoleAdmin` function to track created roles.
function _setRoleAdmin(uint64 roleId, uint64 admin) internal override {
_trackRole(roleId);
Copy link
Member

@miguelmtzinf miguelmtzinf Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, but we do not know which role is the admin role of a given role.
same for guardian

Copy link
Contributor Author

@Kogaroshi Kogaroshi Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

struct Role {
// Members of the role.
mapping(address user => Access access) members;
// Admin who can grant or revoke permissions.
uint64 admin;
// Guardian who can cancel operations targeting functions that need this role.
uint64 guardian;
// Delay in which the role takes effect after being granted.
Time.Delay grantDelay;
}

=> can fetch with :
function getRoleAdmin(uint64 roleId) public view virtual returns (uint64) {

function getRoleGuardian(uint64 roleId) public view virtual returns (uint64) {

Copy link
Member

@miguelmtzinf miguelmtzinf Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so we will have all roles stored in a single mapping, no matter whether they are admin/guardian roles or not. Then, it's only possible to detect if the role is admin/guardian role by fetching all existing roles and calling getRoleAdmin and getRoleGuardian for each one, correct?

Copy link
Contributor Author

@Kogaroshi Kogaroshi Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's currently the only way.
Do we also want to introduce Enum sets for the Guardians & Admins, returning a list of roles[] for a given guardian or admin, and the lists of all roles that are set as admin or guardian to another role ? (that would still mean we need to fetch from the admin/guardian to get the list of concerned roles, but would allow to fetch from both direction) ?

@Kogaroshi Kogaroshi changed the base branch from main to dev December 19, 2025 08:09

/// @inheritdoc IAccessManagerEnumerable
function getRole(uint256 index) external view returns (uint64) {
return uint64(_rolesSet.at(index));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we do safecast here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the RoleId that is returned here is always passed as uint64 before being added in the Set, so I don't see a scenario were we can overflow the uint64 when fetching it back.
Kind of like we did with getRoleTargetFunction

/// @param start The starting index for the role list.
/// @param end The ending index for the role list.
/// @return The list of role identifiers.
function getRoles(uint256 start, uint256 end) external view returns (uint64[] memory);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the main motivation that this just comes for free with the data structure? I imagine that it will be used either to get a specific role or all roles.

What if we just made these private variables public and just expose the simple getters like at an index, or all the roles? Then integrators can just do this kind of access on their own

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could remove given that we have getters for items and length, but I'm fine adding this getter for ease of integration (the set structure provides a function to do it and makes sense to make integrators' lives easier)

mapping(uint64 roleId => EnumerableSet.AddressSet) private _roleTargets;

/// @dev Map of target contract addresses to their current role identifiers.
mapping(address target => uint64 roleId) private _targetRoles;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
mapping(address target => uint64 roleId) private _targetRoles;
mapping(address target => uint64) private _targetRoles;

consistency across codebase

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disagree i think this is needed here

@Kogaroshi Kogaroshi requested a review from miguelmtzinf January 8, 2026 09:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants